package com.youlin.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
public class MyTX {

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    public void txManager (CyclicBarrier cyclicBarrier, AtomicBoolean rollbackFlag, Runnable runnable) {

        TransactionStatus transactionStatus1 = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            runnable.run();
            System.out.printf("\033[33m %s ===>> 我干完活了 \033[0m\n", Thread.currentThread().getName());
        }  catch (Exception e) {
            e.printStackTrace();
            System.out.printf("\033[31m %s ===>> 我错啦，我要回滚了 \033[0m\n", Thread.currentThread().getName());
            rollbackFlag.set(true);
            dataSourceTransactionManager.rollback(transactionStatus1);
        } finally {
            try {
                System.out.printf("\033[34m %s ===>> 我已经准备好了，等待中 ··· ··· \033[0m\n", Thread.currentThread().getName());
                cyclicBarrier.await();
            } catch (Exception e) {}
            if (rollbackFlag.get()) {
                System.out.printf("\033[31m %s ===>> 别人错啦，我要回滚了 \033[0m\n", Thread.currentThread().getName());
                dataSourceTransactionManager.rollback(transactionStatus1);
            } else {
                System.out.printf("\033[32m %s ===>> 大家都OK，我要提交了 \033[0m\n", Thread.currentThread().getName());
                dataSourceTransactionManager.commit(transactionStatus1);
            }
        }
    }

    public Runnable txRunnable (CyclicBarrier cyclicBarrier, AtomicBoolean rollbackFlag, Runnable runnable) {

        return () -> txManager(cyclicBarrier, rollbackFlag, runnable);
    }

}
